package com.bci.pwtz.service.impl;

import java.text.MessageFormat;
import java.util.Date;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;

import com.bci.pwtz.common.PwtzConstants;
import com.bci.pwtz.common.util.PwtzUtils;
import com.bci.pwtz.exception.PwtzDatabaseException;
import com.bci.pwtz.exception.VerifyCodeIsBusyException;
import com.bci.pwtz.exception.VisitCountIsOverTheLimitException;
import com.bci.pwtz.mysql.dao.VerifyCodeHistoryMapper;
import com.bci.pwtz.mysql.dao.VerifyCodeMapper;
import com.bci.pwtz.mysql.model.SmsSendLog;
import com.bci.pwtz.mysql.model.VerifyCode;
import com.bci.pwtz.mysql.model.VerifyCodeHistory;
import com.bci.pwtz.service.SmsSendLogService;
import com.bci.pwtz.service.VerifyCodeService;
import com.bci.pwtz.service.sms.SendSmsService;

/**
 * 一句话描述 <br/>
 * <p>
 * Description:<br/>
 * <p>
 * TODO 详细描述
 * 
 * <p>
 * For Examples <br/>
 * 
 * <PRE>
 *      TODO 代码使用示例
 * </PRE>
 * <p>
 */
@Service
public class VerifyCodeServiceImpl implements VerifyCodeService
{

    private VerifyCodeMapper verifyCodeMapper;
    
    private VerifyCodeHistoryMapper verifyCodeHistoryMapper;
    
    /**
     * @return the verifyCodeMapper
     */
    public VerifyCodeMapper getVerifyCodeMapper()
    {
        return verifyCodeMapper;
    }

    /**
     * @param verifyCodeMapper the verifyCodeMapper to set
     */
    public void setVerifyCodeMapper(VerifyCodeMapper verifyCodeMapper)
    {
        this.verifyCodeMapper = verifyCodeMapper;
    }
    
    /**
     * @return the verifyCodeHistoryMapper
     */
    public VerifyCodeHistoryMapper getVerifyCodeHistoryMapper()
    {
        return verifyCodeHistoryMapper;
    }

    /**
     * @param verifyCodeHistoryMapper the verifyCodeHistoryMapper to set
     */
    public void setVerifyCodeHistoryMapper(VerifyCodeHistoryMapper verifyCodeHistoryMapper)
    {
        this.verifyCodeHistoryMapper = verifyCodeHistoryMapper;
    }
    
    private SendSmsService sendSmsService;
    public void setSendSmsService(SendSmsService sendSmsService)
    {
        this.sendSmsService = sendSmsService;
    }

    public void setSmsSendLogService(SmsSendLogService smsSendLogService)
    {
        this.smsSendLogService = smsSendLogService;
    }

    private SmsSendLogService     smsSendLogService;

    private static final Logger _logger = Logger.getLogger(VerifyCodeServiceImpl.class);
    
    @Override
    public String getCode(String mobile,int type) throws PwtzDatabaseException, VerifyCodeIsBusyException, VisitCountIsOverTheLimitException
    {
        int result=0;
        if (_logger.isInfoEnabled())
        {
            _logger.info("getCode:|mobile=" + mobile);
        }
        if(verifyCodeHistoryMapper.selectTodayHistory(mobile)>=PwtzConstants.MAX_COUNT_VERIFY_CODE_DAILY){
            throw new VisitCountIsOverTheLimitException();
        }
        String code = PwtzUtils.getRandomNumber(6);
        try
        {
            VerifyCode oldVerifyCode = verifyCodeMapper.selectByMobile(mobile);
            if(oldVerifyCode!=null){
                Date createTime = oldVerifyCode.getCreateTime();
                Date vailddate = PwtzUtils.getMinuteAfter(createTime,PwtzConstants.VERIFY_CODE_VAILD);
//                Date vailddate = PwtzUtils.getMinuteAfter(createTime,1);
                int i = new Date().compareTo(vailddate);
                if(i<0){
                    throw new VerifyCodeIsBusyException();
                }
                verifyCodeMapper.deleteByMobile(mobile);
            }
            VerifyCode verifyCode = new VerifyCode();
            verifyCode.setVerifyCode(code);
            verifyCode.setMobile(mobile);
            verifyCode.setType(type);
            verifyCode.setCreateTime(new Date());
            result = verifyCodeMapper.insertSelective(verifyCode);
            String msg = "";
            switch(type)
            {
                default:
                case 1:
                    msg = MessageFormat.format(PwtzConstants.GET_REGISTER_CODE_MSG,code);
                    break;
                case 2:
                    msg = MessageFormat.format(PwtzConstants.GET_FORGET_PASSWORD_CODE_MSG,code);
                    break;
                    
                case 3:
                    msg = MessageFormat.format(PwtzConstants.GET_SWITCH_TEL_CODE_MSG,code);
                    break;
            }
            String smsReturn = "-1";
            try
            {
                smsReturn = sendSmsService.batchSend(new String[]{mobile}, msg, null, null);
            }
            catch(Exception e)
            {
                _logger.error(ExceptionUtils.getStackTrace(e));
            }
            try
            {
                if ("0".equals(smsReturn) || "1".equals(smsReturn))
                {
                    SmsSendLog smsSendLog = new SmsSendLog();
                    smsSendLog.setMobile(mobile);
                    smsSendLog.setContent(msg);
                    smsSendLogService.add(smsSendLog);
                }
                else
                {
                    _logger.error("短信验证码下发失败,smsReturn="+smsReturn);
                }
            }
            catch (PwtzDatabaseException e)
            {
                _logger.error(ExceptionUtils.getStackTrace(e));
            }
            
            VerifyCodeHistory verifyCodeHistory = new VerifyCodeHistory();
            verifyCodeHistory.setVerifyCode(code);
            verifyCodeHistory.setMobile(mobile);
            verifyCodeHistory.setType(type);
            verifyCodeHistory.setCreateTime(new Date());
            verifyCodeHistoryMapper.insertSelective(verifyCodeHistory);
        }
        catch (DataAccessException e)
        {
            _logger.error(ExceptionUtils.getStackTrace(e));
            throw new PwtzDatabaseException();
        }
        if(result>0){
            return code;
        }else{
            return "";
        }
    }
    
    @Override
    public int validateCode(String mobile,String code) throws PwtzDatabaseException
    {
        int result = 0;
        if (_logger.isInfoEnabled())
        {
            _logger.info("selectCountByName:mobile=" + mobile);
        }
        try
        {
            result = verifyCodeMapper.validateCode(mobile,code,PwtzConstants.VERIFY_CODE_VAILD);
        }
        catch (DataAccessException e)
        {
            _logger.error(ExceptionUtils.getStackTrace(e));
            throw new PwtzDatabaseException();
        }
        return result;
    }
}
